#include"../../inc/local/DictProducer.h"

#include <dirent.h>
#include <string>
#include <vector>
#include <regex>
#include <fstream>
#include <iostream>
#include <unordered_map>
using std::vector;
using std::string;
using std::unordered_map;
using std::ifstream;
using std::ofstream;

namespace SC
{
    DictProducer::DictProducer(const string& en_dir, const string& ch_dir, const string& en_dict, const string& ch_dict, SplitToolCppJieba* split)
    : _english_dir(en_dir), _chinese_dir(ch_dir), _english_dict(en_dict), _chinese_dict(ch_dict), _splitTool(split)
    {
        init();
    }

    unordered_map<string, int>& DictProducer::getDict()
    {
        return _dict;
    }

    void DictProducer::show_dict()
    {
        for(auto & k : _dict)
            std::cout << k.first << " : " << k.second << std::endl; 
    }

    void DictProducer::Convert(string& word)
    {
        for(auto & k : word)
            if(k >= 'A' && k <= 'Z')
                k += 32;
    }

    void DictProducer::build_English_dict(const string& dir)
    {
        getfiles(dir);
        string lines;
        string word;
        for(auto & file : _files)
        {
            ifstream ifs(file);
            if(!ifs.good())
            {
                logError("openfile Err");
                exit(1);
            }

            while (getline(ifs, lines))
            {
                if(lines[lines.size() - 1] == '\r') 
                    _dict.erase(lines.substr(0, lines.size() - 1));
                else 
                    _dict.erase(lines);
            
                lines = std::regex_replace(lines, std::regex("[^a-zA-Z0-9]"), " ");     // 正则表达式，将标点符号转换为空格
                stringstream ss(lines);
                while (ss >> word)
                {
                    Convert(word);
                    _dict[word]++;
                }
            }
        }
    }

    void DictProducer::build_Chinese_dict(const string& dir)
    {
        getfiles(dir);
        string lines;
        stringstream buf;

        for(auto & file : _files)
        {
            ifstream ifs(file, ifstream::in);
            if (!ifs.good())
            {
                logError("open file");
                exit(1);
            }

            string lines;
            while (getline(ifs, lines))
            {
                vector<string> ans = _splitTool->cut(lines);
                for (auto &e : ans)
                {
                    _dict[e]++;
                }
            }
            logInfo(file, " get");
        }       
        logInfo("cut finish");
    }
    
    void DictProducer::store_dict(const string& file)
    {
        ofstream ofs(file);
        if(!ofs.good())
        {
            logError("store_dict");
            exit(1);
        }

        for(auto & k : _dict)
            ofs << k.first << " " << k.second << "\n";
        
        ofs.close();
    }

    void DictProducer::getfiles(const string& cdir)
    {
        DIR * dir;
        struct dirent * ptr;

        if((dir = opendir(cdir.c_str())) == nullptr) 
        {
            logError("Open dir error!");
            exit(1);
        }
        logDebug("dir = ", cdir.c_str());

        char * abs_path = nullptr;
        if((abs_path = realpath(cdir.c_str(), nullptr)) == nullptr) 
        {
            logError("realpath");
            exit(1);
        }

        while((ptr = readdir(dir)) != nullptr) 
            if(ptr->d_type == DT_REG) 
                _files.push_back(std::string(abs_path).append("/").append(ptr->d_name));
    }

    void DictProducer::init()
    {
        logInfo("init Dict");
        build_English_dict(_english_dir);
        store_dict(_english_dict);
        build_Chinese_dict(_chinese_dir);
        store_dict(_chinese_dict);
        logInfo("Local Dict Created");
    }

    void DictProducer::remover()
    {

    }
} // namespace SC
